package serova.valeriya.electricity;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

public class AnalysisTariffData {
	private static final Logger LOGGER = Logger.getLogger(AnalysisTariffData.class);
	private static final String delimiter = "[RatesByCategory]";

	private static List <String> getCategoryThresholdInformation(
			List <String> fileContent) {
		List <String> categoriesAndThresholds = new ArrayList<String>();
		int toIndex = fileContent.indexOf(delimiter);
		categoriesAndThresholds = fileContent.subList(1, (toIndex - 1));
		return categoriesAndThresholds;
	}

	private static List <String> getRatesByCategoryInformation(
			List <String> fileContent) {
		List <String> categoriesAndRates = new ArrayList<String>();
		int fromIndex = fileContent.indexOf(delimiter);
		int toIndex = fileContent.size();
		categoriesAndRates = fileContent.subList((fromIndex + 1), (toIndex));
		return categoriesAndRates;
	}

	public static String[] getDataArray(String categoryAndThresholds) {
		String[] array;
		String delimiter = "\\s";
		array = categoryAndThresholds.split(delimiter);
		return array;
	}
			
	

	private static List <Integer> getListThreshold(String[] array) {
		List <Integer> thresholds = new ArrayList<Integer>();
		for (int i = 1; i < array.length; i++) {
			try {
				thresholds.add(Integer.parseInt(array[i]));
			} catch (NumberFormatException ex) {
				LOGGER.error("Данные файла не корректны", ex);
							}
		}

		return thresholds;
	}

	private static String getCategory(String[] array) {
		if((null==array)||(0==array.length)){					
			LOGGER.error("Данная категория отсутствует");
			return StringUtils.EMPTY;	
		}					
		return (array[0]);		
	}

	private static List <Double> getListRate(String[] array) {
		List <Double> rates = new ArrayList<Double>();
		try {
			for (int i = 1; i < array.length; i++) {
				rates.add(Double.parseDouble(array[i]));
			}
		} catch (NumberFormatException s) {
			LOGGER.error("Неправильный формат данных", s);
			UserDialog.printReport("Неправильный формат данных");
		}
		return rates;
	}

	private static List <TarificationRule> getObjectsTarificationRules(List <String> categoryThreshold) {
		List <TarificationRule> tarificationRules = new ArrayList<TarificationRule>();
		List <Integer> threshold = new ArrayList<Integer>();
		String category = null;
		String[] array = null;
		for (String categoryAndThresholds : categoryThreshold) {
			array = getDataArray(categoryAndThresholds);
			threshold = getListThreshold(array);
			category = getCategory(array);
			TarificationRule oneTarificationRule = new TarificationRule();
			oneTarificationRule.setCategory(category);
			oneTarificationRule.setThreshold(threshold);
			tarificationRules.add(oneTarificationRule);
		}
		return tarificationRules;
	}

	private static TarificationRule getAppropriateCategoryTarificationRule(
			final String category, List <TarificationRule> tarificationRules) {		
		TarificationRule elementTarificationRule = (TarificationRule) CollectionUtils.find(tarificationRules, new Predicate() {
					public boolean evaluate(Object oneTarificationRule) {
						TarificationRule elementTarificationRule = (TarificationRule) oneTarificationRule;
						return elementTarificationRule.getCategory().equals(category);
					}
				});
		return elementTarificationRule;
	}
	

	private static void initializeTarificationRuleWithRate(List <String> ratesSection, List <TarificationRule> tarificationRules) {
		List <Double> rate = new ArrayList <Double>();
		String category = null;
		String[] array = null;
		for (String categoryAndRates : ratesSection) {
			array = getDataArray(categoryAndRates);
			rate = getListRate(array);
			category = getCategory(array);
			TarificationRule elementTarificationRule = getAppropriateCategoryTarificationRule(category, tarificationRules);
			elementTarificationRule.setRate(rate);
		}
	}

	public static double getTarif(String category, int electricity,	List <String> fileContent) {
		double electricityPrice;
		List <String> categoriesAndThresholds = getCategoryThresholdInformation(fileContent);
		List <String> categoriesAndRates = getRatesByCategoryInformation(fileContent);
		List <TarificationRule> tarificationRules = getObjectsTarificationRules(categoriesAndThresholds);
		initializeTarificationRuleWithRate(categoriesAndRates, tarificationRules);
		TarificationRule elementTarificationRule = getAppropriateCategoryTarificationRule(category, tarificationRules);
		electricityPrice = elementTarificationRule.chooseTarif(electricity);
		return electricityPrice;
	}
}
